Implicit Rules of `make`
make
有一些隐含的(默认的)推导规则,掌握这些隐含规则不仅能帮我们简化 Makefile 的编写,也能避免我们写出的 Makefile 在 make
时出现奇怪的现象。
不过在此之前我们需要先了解一下 Makefile 当中的自动化变量,可以极大地方便我们编写 Makefile,让我们更容易写出一些规则的“模板”。
另外,准确说来自动化变量的名称是不包括前面的那个 $
号的,那不过表示对这个自动化变量进行求值,所以下表也没列出(这也意味着 $@
和 $(@)
是等效的)。
自动化变量 | 意义 |
---|---|
@ |
目标集合 |
% |
仅当目标是函数库文件(UNIX下的 .a 文件,Windows下的 .lib 文件)时,其值为依赖文件,否则为空 |
< |
依赖目标中的第一个目标 |
? |
所有比目标新的依赖目标的集合,以空格分隔 |
^ |
所有依赖目标的集合(去重),以空格分隔 |
+ |
所有依赖目标的集合(不去重),以空格分隔 |
接下来就是各种各样的隐含规则了。
%.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $? %.o: %.C $(CXX) $(CFLAGS) $(CPPFLAGS) -c -o $@ $? %.o: %.CC $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $? %.o: %.p $(PC) -c $(PFLAGS) $? -o $@ %.o: %.f $(FC) -c $(FFLAGS) $? -o $@ %.f: %.F $(FC) -F $(CPPFLAGS) $(FFLAGS) $? -o $@ %.f: %.r $(FC) -F $(FFLAGS) $(RFLAGS) $? -o $@ %.o: %.F $(FC) -c $(FFLAGS) $(CPPFLAGS) $? -o $@ %.o: %.r $(FC) -c $(FFLAGS) $(RFLAGS) $? -o $@ %.sym: %.def $(M2C) $(M2FLAGS) $(DEFFLAGS) $? -o $@ %.o: %.mod $(M2C) $(M2FLAGS) $(MODFLAGS) $? -o $@ %.o: %.s $(AS) $(ASFLAGS) $? -o $@ %.s: %.S $(CC) -E $(CPPFLAGS) $? > $@ %: %.o $(CC) $(LDFLAGS) $? $(LOADLIBES) $(LDLIBS) -o $@ %.c: %.y $(YACC) $(YFLAGS) $? mv -f y.tab.c %@ %.c: %.l $(LEX) $(LFLAGS) -t $? > $@
最后再说一个小技巧,如果某目标依赖某文件,但在编译该目标的时候又不需要编译器编译该依赖文件(比如某目标 foo.o
依赖 bar.h
,但是编译 foo.o
的时候其实是不用将 bar.h
写到编译命令里的,但如果不在依赖关系里写出的话,更新了 bar.h
又不能 make
时自行重新编译 foo.c
),可以考虑这么做:
foo.o: foo.c bar.h $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $(*F).c